#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""量子金融分析系统 - 工具模块
提供日志记录、文件操作、异常处理等通用工具功能"""

import os
import sys
import json
import time
import traceback
import logging
from datetime import datetime

class Logger:
    """日志记录器
    提供统一的日志记录功能"""
    
    # 日志级别配置
    LOG_LEVELS = {
        "DEBUG": logging.DEBUG,
        "INFO": logging.INFO,
        "WARNING": logging.WARNING,
        "ERROR": logging.ERROR,
        "CRITICAL": logging.CRITICAL
    }
    
    # 初始化日志配置
    @classmethod
    def init_logger(cls, log_file=None, log_level="INFO"):
        """初始化日志记录器
        
        Args:
            log_file: 日志文件路径
            log_level: 日志级别
        """
        # 设置日志格式
        log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        logging.basicConfig(
            level=cls.LOG_LEVELS.get(log_level, logging.INFO),
            format=log_format,
            handlers=[
                logging.StreamHandler(sys.stdout)
            ]
        )
        
        # 如果指定了日志文件，添加文件处理器
        if log_file:
            # 确保日志目录存在
            log_dir = os.path.dirname(log_file)
            if log_dir and not os.path.exists(log_dir):
                os.makedirs(log_dir)
            
            file_handler = logging.FileHandler(log_file, encoding='utf-8')
            file_handler.setFormatter(logging.Formatter(log_format))
            logging.getLogger().addHandler(file_handler)
    
    @classmethod
    def log_debug(cls, message):
        """记录调试信息"""
        logging.debug(message)
        
    @classmethod
    def log_info(cls, message):
        """记录一般信息"""
        logging.info(message)
        print(f"[INFO] {message}")
    
    @classmethod
    def log_warning(cls, message):
        """记录警告信息"""
        logging.warning(message)
        print(f"[WARNING] {message}")
    
    @classmethod
    def log_error(cls, message):
        """记录错误信息"""
        logging.error(message)
        print(f"[ERROR] {message}")
    
    @classmethod
    def log_critical(cls, message):
        """记录严重错误信息"""
        logging.critical(message)
        print(f"[CRITICAL] {message}")

class FileUtils:
    """文件操作工具类
    提供文件读写、目录操作等功能"""
    
    @staticmethod
    def read_file(file_path):
        """读取文件内容
        
        Args:
            file_path: 文件路径
            
        Returns:
            str: 文件内容，失败返回None
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception as e:
            Logger.log_error(f"读取文件失败: {file_path}, 错误: {str(e)}")
            return None
    
    @staticmethod
    def write_file(file_path, content):
        """写入文件内容
        
        Args:
            file_path: 文件路径
            content: 要写入的内容
            
        Returns:
            bool: 是否写入成功
        """
        try:
            # 确保目录存在
            dir_path = os.path.dirname(file_path)
            if dir_path and not os.path.exists(dir_path):
                os.makedirs(dir_path)
            
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            return True
        except Exception as e:
            Logger.log_error(f"写入文件失败: {file_path}, 错误: {str(e)}")
            return False
    
    @staticmethod
    def read_json(file_path):
        """读取JSON文件
        
        Args:
            file_path: 文件路径
            
        Returns:
            dict: JSON数据，失败返回None
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception as e:
            Logger.log_error(f"读取JSON文件失败: {file_path}, 错误: {str(e)}")
            return None
    
    @staticmethod
    def write_json(file_path, data):
        """写入JSON文件
        
        Args:
            file_path: 文件路径
            data: 要写入的JSON数据
            
        Returns:
            bool: 是否写入成功
        """
        try:
            # 确保目录存在
            dir_path = os.path.dirname(file_path)
            if dir_path and not os.path.exists(dir_path):
                os.makedirs(dir_path)
            
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=4)
            return True
        except Exception as e:
            Logger.log_error(f"写入JSON文件失败: {file_path}, 错误: {str(e)}")
            return False
    
    @staticmethod
    def file_exists(file_path):
        """检查文件是否存在
        
        Args:
            file_path: 文件路径
            
        Returns:
            bool: 文件是否存在
        """
        return os.path.isfile(file_path)
    
    @staticmethod
    def create_directory(dir_path):
        """创建目录
        
        Args:
            dir_path: 目录路径
            
        Returns:
            bool: 是否创建成功
        """
        try:
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            return True
        except Exception as e:
            Logger.log_error(f"创建目录失败: {dir_path}, 错误: {str(e)}")
            return False

class ExceptionHandler:
    """异常处理器
    提供统一的异常处理功能"""
    
    @classmethod
    def handle_exceptions(cls, func):
        """异常处理装饰器
        
        Args:
            func: 要装饰的函数
            
        Returns:
            wrapper: 装饰后的函数
        """
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                # 获取函数信息
                func_name = func.__name__
                class_name = args[0].__class__.__name__ if args and hasattr(args[0], '__class__') else 'UnknownClass'
                
                # 记录异常信息
                error_message = f"{class_name}.{func_name} 执行异常: {str(e)}"
                Logger.log_error(error_message)
                Logger.log_error(f"异常栈: {traceback.format_exc()}")
                
                # 返回默认值
                return False
        
        # 保留原函数的元数据
        wrapper.__name__ = func.__name__
        wrapper.__doc__ = func.__doc__
        wrapper.__module__ = func.__module__
        
        return wrapper
    
    @classmethod
    def catch_exceptions(cls, default_return=False):
        """异常捕获装饰器
        
        Args:
            default_return: 异常发生时的默认返回值
            
        Returns:
            decorator: 装饰器函数
        """
        def decorator(func):
            def wrapper(*args, **kwargs):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    # 记录异常信息但不中断程序
                    Logger.log_error(f"{func.__name__} 捕获异常: {str(e)}")
                    return default_return
            
            # 保留原函数的元数据
            wrapper.__name__ = func.__name__
            wrapper.__doc__ = func.__doc__
            wrapper.__module__ = func.__module__
            
            return wrapper
        
        return decorator

# 初始化日志记录器
Logger.init_logger()